﻿using Chromium.WebBrowser;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;

namespace M5.GeminiHybird.Core.XHR
{
    internal class SchemeHandlerRequestEvent
    {
        private WebResource webResource { get; set; }
        private GCHandle gcHandle { get; set; }
        private byte[] responseData { get; set; }
        private int StatusCode { get; set; }
        private string StatusText { get; set; }

        internal void Hander_ProcessRequest(object sender, Chromium.Event.CfxProcessRequestEventArgs e)
        {
            gcHandle = GCHandle.Alloc(this);

            var request = e.Request;
            var callback = e.Callback;

            StatusCode = 200;
            StatusText = "OK";

            //foreach (var item in data.Elements)
            //{
            //    var size = item.GetBytes(item.BytesCount, item.NativePtr);
            //    byte[] buffer = new byte[size];
            //    Marshal.Copy(item.NativePtr, buffer, 0, (int)size);

            //    postParam = Encoding.UTF8.GetString(buffer);

            //}
            var httpMethod = request.Method.ToLower();
            //当前只能处理get与post请求
            if (httpMethod == "get" || httpMethod == "post")
            {
                string rawUrl = request.Url.Replace("http://" + Config.SchemeConfig.Instance.Domain, "");
                Controller.BaseController baseController = Routes.FindController(rawUrl);
                if (baseController == null)
                {
                    StatusCode = 404;
                    StatusText = "Not Found";
                    responseData = Encoding.UTF8.GetBytes($"没有找到{rawUrl}配置的处理程序");
                    callback.Continue();
                    return;
                }

                string routeData = Routes.RouteData(request, rawUrl);
                string result = baseController.Execute(routeData);

                responseData = Encoding.UTF8.GetBytes(result);
            }

            callback.Continue();





            e.SetReturnValue(true);
            e.Callback.Continue();

        }

        internal void Hander_GetResponseHeaders(object sender, Chromium.Event.CfxGetResponseHeadersEventArgs e)
        {

            e.Response.Status = StatusCode;
            e.Response.StatusText = StatusText;
            List<string[]> headerMap = e.Response.GetHeaderMap();
            headerMap.Add(new string[2] { "Access-Control-Allow-Origin", "*" });
            headerMap.Add(new string[2] { "Access-Control-Allow-Methods", "POST, GET, OPTIONS" });
            headerMap.Add(new string[2] { "Access-Control-Allow-Headers", "Origin, Content-Type, Accept" });
            headerMap.Add(new string[2] { "Accept-Language", "zh-CN" });
            headerMap.Add(new string[2] { "Accept", "POST, GET, OPTIONS" });
            headerMap.Add(new string[2] { "Content-Type", "application/json; charset=UTF-8" });


            webResource = new WebResource(responseData == null ? new byte[0] : responseData, "application/json");
            headerMap.Add(new string[2] { "Content-Length", webResource.data.LongLength.ToString() });
            e.Response.SetHeaderMap(headerMap);
            e.ResponseLength = webResource.data.LongLength;
        }

        internal void Hander_ReadResponse(object sender, Chromium.Event.CfxReadResponseEventArgs e)
        {

            int readResponseStreamOffset = 0;

            int bytesToCopy = webResource.data.Length - readResponseStreamOffset;

            if (bytesToCopy > e.BytesToRead)
                bytesToCopy = e.BytesToRead;

            Marshal.Copy(webResource.data, readResponseStreamOffset, e.DataOut, bytesToCopy);

            e.BytesRead = bytesToCopy;

            readResponseStreamOffset += bytesToCopy;

            e.SetReturnValue(true);

            e.Callback.Continue();
            //if (readResponseStreamOffset == webResource.data.Length)
            //{
            gcHandle.Free();
            //}
        }
    }
}
